

//----------------------------------------------------------------------
// * StatHash
//----------------------------------------------------------------------
//
// A hash for storing simple statistics about hits. Note that 
// in many places this hash is used with array syntax, for example:
// h[i]++ 
// looks up entry with key i, increments it's value, and stores it
// back into the hash.  It looks like array access, but it's a hash
// access. 
// 
// CAUTION:  This similarity with arrays is misleading.  For 
// example:
//
// if(h[i] == 0)  
//
// will ALWAYS create an entry (i,0) in h!!!  Must use Contains
// to test for existence of a value.  
//
class StatHash : public hash_map<int,int,hash<int>,equal_to<int> >{
public:

  bool Contains(int key){
	 const StatHash::iterator it = find(key);
	 if (it != end()) return(true);
	 else return(false);
  }

  bool Add(int key,int value){	 
	 insert(value_type(key,value));
  }

  bool Lookup(int key,int &value){
	 const StatHash::iterator it = find(key);
	 if (it != end()){
		value = (*it).second;
		return(true);
	 }
	 value = 0;
	 return(false);
  }

  bool Increment(int key,int amount){
	 StatHash::iterator it = find(key);
	 (*it).second+=amount;
  }

  bool IncrementIfExists(int key,int amount){
	 StatHash::iterator it = find(key);
	 if (it != end()){
		(*it).second+=amount;
	 }
  }

  bool IncrementOrAdd(int key,int value){
	 StatHash::iterator it = find(key);
	 if (it != end()){
		(*it).second += value;
	 }else{
		insert(value_type(key,value));
	 }
  }

  bool AddOrChange(int key,int value){
	 StatHash::iterator it = find(key);
	 if (it != end()){
		(*it).second = value;
	 }else{
		insert(value_type(key,value));
	 }
  }

  bool Change(int key,int value){
	 StatHash::iterator it = find(key);
	 if (it != end()){
		(*it).second = value;
	 }
  }

};
